home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
program
/
libkb100.zip
/
LIBKB-1.00
/
SRC
/
MKTABLES.C
< prev
Wrap
C/C++ Source or Header
|
1996-07-23
|
16KB
|
619 lines
/* mktables.c -- make keyboard tables _kbtable.hh
* Copyright (C) 1995, 1996 Markus F.X.J. Oberhumer
* For conditions of distribution and use, see copyright notice in kb.h
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <kb.h>
#include "_kb.h"
#if defined(__KB_MSDOS)
# include <io.h>
# include <fcntl.h>
#endif
/***********************************************************************
//
************************************************************************/
static unsigned char prefix_scancode[128];
static unsigned char inverse_prefix_scancode[128];
static unsigned short shift_state_table[128];
static unsigned short unshift_state_table[128];
typedef unsigned short table_t;
static table_t alt_table[128];
static table_t control_table[128];
/***********************************************************************
// prefix tables
************************************************************************/
static void init_prefix_tables(void)
{
int i;
unsigned char *t;
t = prefix_scancode; /* E0 table */
/* unknown prefix codes map to scancode 0 */
for (i = 0; i < 128; i++)
t[i] = KB_SCAN_UNKNOWN;
/* prefixed keys which map to keypad */
t[KB_SCAN_SLASH] = KB_SCAN_DIVIDE_PAD;
t[KB_SCAN_ENTER] = KB_SCAN_ENTER_PAD;
/* prefixed keys on keypad which map to other keys */
t[KB_SCAN_MULTIPLY_PAD] = KB_SCAN_PRINT;
t[KB_SCAN_7_PAD] = KB_SCAN_HOME;
t[KB_SCAN_8_PAD] = KB_SCAN_UP;
t[KB_SCAN_9_PAD] = KB_SCAN_PGUP;
t[KB_SCAN_4_PAD] = KB_SCAN_LEFT;
t[KB_SCAN_6_PAD] = KB_SCAN_RIGHT;
t[KB_SCAN_1_PAD] = KB_SCAN_END;
t[KB_SCAN_2_PAD] = KB_SCAN_DOWN;
t[KB_SCAN_3_PAD] = KB_SCAN_PGDN;
t[KB_SCAN_0_PAD] = KB_SCAN_INSERT;
t[KB_SCAN_PERIOD_PAD] = KB_SCAN_DELETE;
/* prefixed shift keys */
t[KB_SCAN_LCONTROL] = KB_SCAN_RCONTROL;
t[KB_SCAN_ALT] = KB_SCAN_ALTGR;
t[KB_SCAN_LSHIFT] = KB_SCAN_UNUSED_VIRTUAL;
t[KB_SCAN_RSHIFT] = KB_SCAN_UNUSED_VIRTUAL;
/* prefixed special keys */
t[KB_SCAN_NUMLOCK] = KB_SCAN_PAUSE_VIRTUAL;
t[KB_SCAN_SCRLOCK] = KB_SCAN_CONTROL_BREAK_VIRTUAL;
for (i = KB_SCAN_F12 + 1; i < 128; i++)
assert(prefix_scancode[i] == KB_SCAN_UNKNOWN);
/* New Microsoft keyboard is rumoured to have
* e0 5b (left window button), e0 5c (right window button),
* e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
* [or: Windows_L, Windows_R, TaskMan]
*/
t[0x5b] = KB_SCAN_LBANNER;
t[0x5c] = KB_SCAN_RBANNER;
t[0x5d] = KB_SCAN_RMENU;
for (i = KB_SCAN_MAX_RAW + 1; i < 128; i++)
assert(prefix_scancode[i] == KB_SCAN_UNKNOWN);
t = inverse_prefix_scancode;
for (i = 0; i < 128; i++)
t[i] = i;
for (i = 0; i < 128; i++)
if (prefix_scancode[i] != KB_SCAN_UNKNOWN)
t[prefix_scancode[i]] = i;
}
/***********************************************************************
// shift-state tables
************************************************************************/
static void init_shift_state_tables(void)
{
int i;
unsigned short *t;
const unsigned short virt = KB_SHIFT_VIRTUAL | KB_SHIFT_NO_PRESS;
const unsigned short unkn = KB_SHIFT_UNKNOWN | KB_SHIFT_NO_PRESS;
t = shift_state_table;
for (i = 0; i < 128; i++)
t[i] = 0;
/* shift keys */
t[KB_SCAN_LSHIFT] |= KB_SHIFT_LSHIFT | KB_SHIFT_NO_PRESS;
t[KB_SCAN_RSHIFT] |= KB_SHIFT_RSHIFT | KB_SHIFT_NO_PRESS;
t[KB_SCAN_LCONTROL] |= KB_SHIFT_LCONTROL | KB_SHIFT_NO_PRESS;
t[KB_SCAN_RCONTROL] |= KB_SHIFT_RCONTROL | KB_SHIFT_NO_PRESS;
t[KB_SCAN_ALT] |= KB_SHIFT_ALT | KB_SHIFT_NO_PRESS;
t[KB_SCAN_ALTGR] |= KB_SHIFT_ALTGR | KB_SHIFT_NO_PRESS;
/* these are toggles and therefore not in the unshift state table */
t[KB_SCAN_CAPSLOCK] |= KB_SHIFT_CAPSLOCK | KB_SHIFT_NO_PRESS;
t[KB_SCAN_NUMLOCK] |= KB_SHIFT_NUMLOCK | KB_SHIFT_NO_PRESS;
t[KB_SCAN_SCRLOCK] |= KB_SHIFT_SCRLOCK | KB_SHIFT_NO_PRESS;
/* these are toggles that DO produce a keypress */
t[KB_SCAN_INSERT] |= KB_SHIFT_INSERT;
/* these are toggles for virtual keys */
t[KB_SCAN_CONTROL_BREAK_VIRTUAL] |= KB_SHIFT_CONTROL_BREAK | virt;
t[KB_SCAN_PAUSE_VIRTUAL] |= KB_SHIFT_PAUSE | virt;
/* other virtual keys */
t[KB_SCAN_UNUSED_VIRTUAL] |= virt;
/* other keys */
t[KB_SCAN_LAST_CONSOLE] |= KB_SHIFT_NO_PRESS;
t[KB_SCAN_LBANNER] |= KB_SHIFT_NO_PRESS;
t[KB_SCAN_RBANNER] |= KB_SHIFT_NO_PRESS;
t[KB_SCAN_RMENU] |= KB_SHIFT_NO_PRESS;
/* t[KB_SCAN_PRINT] |= KB_SHIFT_NO_PRESS; Ctrl+Print DOES generate a code */
/* unknown keys */
i = KB_SCAN_UNKNOWN;
if (t[i] == 0)
t[i] |= unkn;
i = 85;
if (t[i] == 0)
t[i] |= unkn;
for (i = 89; i < 96; i++)
if (t[i] == 0)
t[i] |= unkn;
for (i = 112; i < 128; i++)
if (t[i] == 0)
t[i] |= unkn;
/* NOT USED */
#if defined(KB_SHIFT_NO_NAME)
for (i = 0; i < 128; i++)
{
const char *p = kb_keyname(i);
if (p == NULL || *p == 0)
t[i] |= KB_SHIFT_NO_NAME;
}
#endif
t = unshift_state_table;
for (i = 0; i < 128; i++)
t[i] = 0;
t[KB_SCAN_LSHIFT] = KB_SHIFT_LSHIFT;
t[KB_SCAN_RSHIFT] = KB_SHIFT_RSHIFT;
t[KB_SCAN_LCONTROL] = KB_SHIFT_LCONTROL;
t[KB_SCAN_RCONTROL] = KB_SHIFT_RCONTROL;
t[KB_SCAN_ALT] = KB_SHIFT_ALT;
t[KB_SCAN_ALTGR] = KB_SHIFT_ALTGR;
/* negate for use with & (and) */
for (i = 0; i < 128; i++)
t[i] = ~t[i];
}
/***********************************************************************
// utility stuff
************************************************************************/
static int no_code(int i)
{
assert(i >= 0 && i < 128);
return KB_ANY_MASK(shift_state_table[i],
(KB_SHIFT_NO_PRESS | KB_SHIFT_UNKNOWN | KB_SHIFT_VIRTUAL));
}
static int default_code(int i)
{
assert(i >= 0 && i < 128);
if (no_code(i))
return 0;
if (i >= KB_SCAN_F1 && i <= KB_SCAN_F10)
return 0;
if (i >= KB_SCAN_F11 && i <= KB_SCAN_F12)
return 0;
if (i == KB_SCAN_PRINT)
return 0;
return inverse_prefix_scancode[i];
}
static void cleanup_table(table_t *t)
{
int i;
for (i = 0; i < 128; i++)
if (no_code(i))
t[i] = 0;
}
/***********************************************************************
// These tables are hardcoded for American keyboards.
************************************************************************/
/* unshifted ASCII for scan codes */
static table_t plain_table[128] =
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
0 ,27 ,'1','2','3','4','5','6','7','8','9','0','-','=',8 ,9 , /* 0 */
'q','w','e','r','t','y','u','i','o','p','[',']',13 ,0 ,'a','s', /* 1 */
'd','f','g','h','j','k','l',';',39 ,'`',0 ,92 ,'z','x','c','v', /* 2 */
'b','n','m',',','.','/',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , /* 3 */
0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', /* 4 */
'2','3','0','.',0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , /* 5 */
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , /* 6 */
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 /* 7 */
};
/* shifted ASCII for scan codes */
static table_t shift_table[128] =
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
0 ,27 ,'!','@','#','$','%','^','&','*','(',')','_','+',8 ,9 , /* 0 */
'Q','W','E','R','T','Y','U','I','O','P','{','}',13 ,0 ,'A','S', /* 1 */
'D','F','G','H','J','K','L',':',34 ,'~',0 ,'|','Z','X','C','V', /* 2 */
'B','N','M','<','>','?',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , /* 3 */
0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', /* 4 */
'2','3','0','.',0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , /* 5 */
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , /* 6 */
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 /* 7 */
};
static void prepare_table(table_t *t)
{
int i;
t[KB_SCAN_ENTER_PAD] = 13;
t[KB_SCAN_DIVIDE_PAD] = '/';
if (t[KB_SCAN_LESS] == 0)
t[KB_SCAN_LESS] = t[KB_SCAN_BACKSLASH];
for (i = 0; i < 128; i++)
if (t[i] == 0)
t[i] = default_code(i);
}
static void init_plain_table(void)
{
table_t *t = plain_table;
int i, j;
prepare_table(t);
for (i = j = KB_SCAN_F1; i